/*
 * @(#)Snake.java    Oct 12, 2010
 *
 * Copyright 2009 Nyber Shanghai, Inc. All rights reserved.
 */

package com.lab.puzzle;

/**
 *  
    int i = 5;   
    1  2  3  4  5   
    16 17 18 19 6   
    15 24 25 20 7   
    14 23 22 21 8   
    13 12 11 10 9
    
    int i=6   
    1  2  3  4  5   6   
    20 21 22 23 24  7   
    19 32 33 34 25  8   
    18 31 36 35 26  9   
    17 30 29 28 27 10   
    16 15 14 13 12 11  
    
    解题思路: 
        1. 当前元素的位置.
        2. 下个元素的位置.
 *
 * @author nickevin@gmail.com
 * @version Oct 12, 2010 3:28:59 PM
 */

public class Snake {

    private int length, initial = 1;
    private int[][] snake;
    private static Direction next = Direction.RIGHT;

    public Snake(int length) {
        this.length = length;
        snake = new int[length][length]; // 默认元素为0.
    }

    private static enum Direction {
        RIGHT, DOWN, LEFT, UP;
    }

    public int[][] initial() {
        int row = 0, column = 0;
        for (int idx = 0, len = length * length; idx < len; idx++) {
            snake[row][column] = initial++;
            determineDirection(row, column);
            switch (next) {
            case RIGHT:
                column++;
                break;
            case DOWN:
                row++;
                break;
            case LEFT:
                column--;
                break;
            case UP:
                row--;
                break;
            default:
                System.out.println("error");
            }
        }

        return snake;
    }

    private void determineDirection(int row, int column) {
        switch (next) {
        case RIGHT: {
            if (column == length - 1 || snake[row][column + 1] != 0 /*内部换方向标记 */) {
                next = Direction.DOWN;
            }
            break;
        }
        case DOWN: {
            if (row == length - 1 || snake[row + 1][column] != 0) {
                next = Direction.LEFT;
            }
            break;
        }
        case LEFT: {
            if (column == 0 || snake[row][column - 1] != 0) {
                next = Direction.UP;
            }
            break;
        }
        case UP: {
            if (snake[row - 1][column] != 0) {
                next = Direction.RIGHT;
            }
            break;
        }
        }
    }
}
